package com.ruoyi.crm.service.impl;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.AuditStatus;
import com.ruoyi.common.enums.flow.FlowTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.flow.FlowDTO;
import com.ruoyi.common.utils.flow.FlowParamsUtils;
import com.ruoyi.crm.domain.*;
import com.ruoyi.crm.mapper.CrmOrderMapper;
import com.ruoyi.crm.service.ICrmCustomerService;
import com.ruoyi.crm.service.ICrmOrderService;
import com.ruoyi.crm.service.ICrmProductService;
import com.ruoyi.crm.utils.ThreadLocalUtils;
import com.warm.flow.core.dto.FlowParams;
import com.warm.flow.core.entity.Instance;
import com.warm.flow.core.enums.SkipType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.crm.mapper.CrmOrderProductDiscountMapper;
import com.ruoyi.crm.service.ICrmOrderProductDiscountService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

/**
 * 商机产品折扣Service业务层处理
 *
 * @author yanwenliang
 * @date 2024-11-04
 */
@Service
public class CrmOrderProductDiscountServiceImpl extends ServiceImpl<CrmOrderProductDiscountMapper, CrmOrderProductDiscount> implements ICrmOrderProductDiscountService
{
    @Autowired
    private CrmOrderProductDiscountMapper crmOrderProductDiscountMapper;

    @Autowired
    private ICrmOrderService crmOrderService;

    @Autowired
    private ICrmCustomerService crmCustomerService;

    @Autowired
    private ICrmProductService crmProductService;

    /**
     * 查询商机产品折扣
     *
     * @param discountId 商机产品折扣主键
     * @return 商机产品折扣
     */
    @Override
    public CrmOrderProductDiscount selectCrmOrderProductDiscountByDiscountId(String discountId)
    {
        return crmOrderProductDiscountMapper.selectCrmOrderProductDiscountByDiscountId(discountId);
    }

    /**
     * 查询商机产品折扣列表
     *
     * @param crmOrderProductDiscount 商机产品折扣
     * @return 商机产品折扣
     */
    @Override
    public List<CrmOrderProductDiscount> selectCrmOrderProductDiscountList(CrmOrderProductDiscount crmOrderProductDiscount)
    {
        if (!SecurityUtils.hasAdmin()){
            crmOrderProductDiscount.setUserId(SecurityUtils.getUserId());
        }
        return crmOrderProductDiscountMapper.selectCrmOrderProductDiscountList(crmOrderProductDiscount);
    }

    /**
     * 新增商机产品折扣
     *
     * @param crmOrderProductDiscount 商机产品折扣
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertCrmOrderProductDiscount(CrmOrderProductDiscount crmOrderProductDiscount) {
        crmOrderProductDiscount.setCreateTime(DateUtils.getNowDate());
        crmOrderProductDiscount.setCreateBy(SecurityUtils.getUsername());
        crmOrderProductDiscount.setUserId(SecurityUtils.getUserId());

        if (StringUtils.isEmpty(crmOrderProductDiscount.getDiscountId())){
            crmOrderProductDiscount.setDiscountId(IdWorker.getIdStr());
        } else {
            // 如果不是第一次申请折扣，则删除原来流程，开启新的流程
            CrmOrderProductDiscount discount = baseMapper.selectById(crmOrderProductDiscount.getDiscountId());
            FlowParamsUtils.remove(discount.getInstanceId());
        }

        crmOrderProductDiscount.setAuditStatus(AuditStatus.AWAIT_SUBMIT.getCode());

        ThreadLocalUtils.set(FlowTypeEnum.FLOW_PRODUCT_DISCOUNT.getInfo() + ":" + crmOrderProductDiscount.getDiscountId(), crmOrderProductDiscount);
        FlowParamsUtils.start(crmOrderProductDiscount, "flow-product-discount", crmOrderProductDiscount.getDiscountId());
        return this.saveOrUpdate(crmOrderProductDiscount);

    }

    /**
     * 修改商机产品折扣
     *
     * @param crmOrderProductDiscount 商机产品折扣
     * @return 结果
     */
    @Override
    public int updateCrmOrderProductDiscount(CrmOrderProductDiscount crmOrderProductDiscount)
    {
        crmOrderProductDiscount.setUpdateTime(DateUtils.getNowDate());
        crmOrderProductDiscount.setUpdateBy(SecurityUtils.getUsername());
        return crmOrderProductDiscountMapper.updateCrmOrderProductDiscount(crmOrderProductDiscount);
    }

    /**
     * 批量删除商机产品折扣
     *
     * @param discountIds 需要删除的商机产品折扣主键
     * @return 结果
     */
    @Override
    public int deleteCrmOrderProductDiscountByDiscountIds(String[] discountIds)
    {
        List<CrmOrderProductDiscount> crmOrderProductDiscounts = baseMapper.selectBatchIds(Arrays.asList(discountIds));
        List<Long> instanceIdList = crmOrderProductDiscounts.stream().map(CrmOrderProductDiscount::getInstanceId).collect(Collectors.toList());
        FlowParamsUtils.remove(instanceIdList);
        return crmOrderProductDiscountMapper.deleteCrmOrderProductDiscountByDiscountIds(discountIds);
    }

    /**
     * 删除商机产品折扣信息
     *
     * @param discountId 商机产品折扣主键
     * @return 结果
     */
    @Override
    public int deleteCrmOrderProductDiscountByDiscountId(String discountId) {
        return crmOrderProductDiscountMapper.deleteCrmOrderProductDiscountByDiscountId(discountId);
    }

    /**
     * 提交
     * @param crmOrderProductDiscount
     * @return
     */
    @Override
    public int submit(CrmOrderProductDiscount crmOrderProductDiscount) {
        crmOrderProductDiscount.setSkipType(SkipType.PASS.getKey());
        FlowParams flowParams = FlowParamsUtils.build(crmOrderProductDiscount, "");
        FlowParamsUtils.skipByInsId(crmOrderProductDiscount, flowParams);
        crmOrderProductDiscount.setAuditStatus(AuditStatus.AWAIT_AUDIT.getCode());
        return crmOrderProductDiscountMapper.updateCrmOrderProductDiscount(crmOrderProductDiscount);
    }

    /**
     * 审核
     * @param crmOrderProductDiscount
     * @return
     */
    @Override
    public int audit(CrmOrderProductDiscount crmOrderProductDiscount) {
        CrmOrderProductDiscount discount = baseMapper.selectById(crmOrderProductDiscount.getDiscountId());

        if (ObjectUtils.isEmpty(discount)){
            throw new ServiceException("产品折扣申请数据不存在，请刷新后重试");
        }

        FlowParamsUtils.skip(crmOrderProductDiscount, "");

        // todo 折扣审批不通过，商机需要修改
//        if(AuditStatus.NOT_PASS.getCode().equals(crmOrderProductDiscount.getAuditStatus())){
//
//        }

        return baseMapper.updateById(crmOrderProductDiscount);

    }

    @Override
    public FlowDTO conversionObj(Serializable id) {
        CrmOrderProductDiscount crmOrderProductDiscount = this.selectCrmOrderProductDiscountByDiscountId(id.toString());
        FlowDTO flowDTO = this.buildFlowDTO(crmOrderProductDiscount);
        return flowDTO;
    }

    @Override
    public FlowDTO conversionObjByLocal(Serializable id) {
        try {
            CrmOrderProductDiscount crmOrderProductDiscount = ThreadLocalUtils.get(FlowTypeEnum.FLOW_PRODUCT_DISCOUNT.getInfo() + ":" + id);
            CrmOrder crmOrder = crmOrderService.getById(crmOrderProductDiscount.getOrderId());
            CrmProduct crmProduct = crmProductService.getById(crmOrderProductDiscount.getProductId());
            crmOrderProductDiscount.setOrderName(crmOrder.getOrderName());
            crmOrderProductDiscount.setProductName(crmProduct.getProductName());
            FlowDTO flowDTO = this.buildFlowDTO(crmOrderProductDiscount);
            return flowDTO;
        } finally {
            ThreadLocalUtils.remove(FlowTypeEnum.FLOW_PRODUCT_DISCOUNT.getInfo() + ":" + id);
        }
    }

    private FlowDTO buildFlowDTO( CrmOrderProductDiscount crmOrderProductDiscount ){
        FlowDTO flowDTO = new FlowDTO(crmOrderProductDiscount);
        Map<String, Object> businessValue = flowDTO.getBusinessValue();
        businessValue.put("商机名称", crmOrderProductDiscount.getOrderName());
        businessValue.put("产品名称", crmOrderProductDiscount.getProductName());
        businessValue.put("折扣后金额", crmOrderProductDiscount.getDiscountPrice());
        return flowDTO;
    }
}
